'''
最大公约数--欧几里得算法
    欧几里得算法: gcd(a,b) = gcd(b,a mod b)
    例: gcd(60,21) = gcd(21,18) = gcd(18,3) = gcd(3,0) = 3

'''
def gcd(a,b):
    while a>0 and b>0:
        a,b = b,a%b
    if b == 0:
        return a

# print(gcd(60,21))

def gcd_1(a,b):
    if b == 0:
        return a
    else:
        return gcd_1(b,a%b)
# print(gcd_1(16,12))

'''
应用:实现分数计算
    利用欧几里得算法实现一个分数类,支持分数的四则运算
'''


class Fraction_cal:
    class Fraction:
        def __init__(self, son, mom):
            # 确保分母不为0
            if mom == 0:
                raise ValueError("分母不能为0")
            # 确保分母为正数
            if mom < 0:
                son = -son
                mom = -mom
            self.son = son
            self.mom = mom
            # 自动约分
            self.simplify()

        def simplify(self):
            # 约分分数
            common_divisor = Fraction_cal().gcd(self.son, self.mom)
            if common_divisor != 0:
                self.son //= common_divisor
                self.mom //= common_divisor

        def __str__(self):
            # 重写字符串显示，方便打印
            if self.mom == 1:
                return f"{self.son}"
            return f"{self.son}/{self.mom}"

    def gcd(self, a, b):
        # 计算最大公约数
        a, b = abs(a), abs(b)  # 处理负数情况
        while b != 0:
            a, b = b, a % b
        return a

    def add(self, a, b):
        # 加法: a + b
        new_son = a.son * b.mom + a.mom * b.son
        new_mom = a.mom * b.mom
        return self.Fraction(new_son, new_mom)

    def subtract(self, a, b):
        # 减法: a - b
        new_son = a.son * b.mom - a.mom * b.son
        new_mom = a.mom * b.mom
        return self.Fraction(new_son, new_mom)

    def multiply(self, a, b):
        # 乘法: a * b
        new_son = a.son * b.son
        new_mom = a.mom * b.mom
        return self.Fraction(new_son, new_mom)

    def divide(self, a, b):
        # 除法: a / b
        if b.son == 0:
            raise ValueError("除数不能为0")
        # 除以一个分数等于乘以它的倒数
        new_son = a.son * b.mom
        new_mom = a.mom * b.son
        return self.Fraction(new_son, new_mom)


# 使用示例
calculator = Fraction_cal()
a = calculator.Fraction(1, 2)
b = calculator.Fraction(1, 3)

print(f"{a} + {b} = {calculator.add(a, b)}")  # 1/2 + 1/3 = 5/6
print(f"{a} - {b} = {calculator.subtract(a, b)}")  # 1/2 - 1/3 = 1/6
print(f"{a} × {b} = {calculator.multiply(a, b)}")  # 1/2 × 1/3 = 1/6
print(f"{a} ÷ {b} = {calculator.divide(a, b)}")  # 1/2 ÷ 1/3 = 3/2

# 更多测试
c = calculator.Fraction(3, 4)
d = calculator.Fraction(2, 5)
print(f"\n{c} + {d} = {calculator.add(c, d)}")  # 3/4 + 2/5 = 23/20
print(f"{c} × {d} = {calculator.multiply(c, d)}")  # 3/4 × 2/5 = 3/10

'''
用 self,other 参数重写代码
'''
class Fraction:
    def __init__(self, son, mom):
        # 确保分母不为0
        if mom == 0:
            raise ValueError("分母不能为0")
        # 确保分母为正数
        if mom < 0:
            son = -son
            mom = -mom
        self.son = son  # 分子
        self.mom = mom  # 分母
        self.simplify()  # 自动约分

    def gcd(self, a, b):
        # 计算最大公约数
        a, b = abs(a), abs(b)
        while b != 0:
            a, b = b, a % b
        return a

    def simplify(self):
        # 约分分数
        common_divisor = self.gcd(self.son, self.mom)
        if common_divisor != 0:
            self.son //= common_divisor
            self.mom //= common_divisor

    # 加法: self + other
    def __add__(self, other):
        new_son = self.son * other.mom + self.mom * other.son
        new_mom = self.mom * other.mom
        return Fraction(new_son, new_mom)

    # 减法: self - other
    def __sub__(self, other):
        new_son = self.son * other.mom - self.mom * other.son
        new_mom = self.mom * other.mom
        return Fraction(new_son, new_mom)

    # 乘法: self * other
    def __mul__(self, other):
        new_son = self.son * other.son
        new_mom = self.mom * other.mom
        return Fraction(new_son, new_mom)

    # 除法: self / other
    def __truediv__(self, other):
        if other.son == 0:
            raise ValueError("除数不能为0")
        new_son = self.son * other.mom
        new_mom = self.mom * other.son
        return Fraction(new_son, new_mom)

    def __str__(self):
        if self.mom == 1:
            return f"{self.son}"
        return f"{self.son}/{self.mom}"


# 使用示例
a = Fraction(1, 2)
b = Fraction(1, 3)

print(f"{a} + {b} = {a + b}")  # 1/2 + 1/3 = 5/6
print(f"{a} - {b} = {a - b}")  # 1/2 - 1/3 = 1/6
print(f"{a} × {b} = {a * b}")  # 1/2 × 1/3 = 1/6
print(f"{a} ÷ {b} = {a / b}")  # 1/2 ÷ 1/3 = 3/2

# 连续运算示例
c = Fraction(3, 4)
d = Fraction(2, 5)
print(f"\n({a} + {b}) × {c} = {(a + b) * c}")  # (1/2 + 1/3) × 3/4 = 5/8
